#include "GameScene.h"
#include "StaticData.h"
#include "FishingJoyData.h"
#include "Fish.h"
#include "FishLayer.h"
#include "MenuLayer.h"
#include "PanelLayer.h"
#include "CannonLayer.h"
#include "BackgroundLayer.h"
#include "TouchLayer.h"
#include "Weapon.h"
#include "GoldCounterLayer.h"
#include "PersonalAudioEngine.h"
USING_NS_CC;
using namespace std;
const string fishingjoy_resource_path="fishingjoy_resource.plist";
GameScene::~GameScene()
{
	//CC_SAFE_RELEASE(_menuLayer);
}
//todo after implemented StartScene,it should be deleted.
void GameScene::preloadResources()
{
	CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fishingjoy_resource_path.c_str());
	StaticData* staticData=StaticData::getInstance();
	int frameCount=staticData->intFromKey("fish_frame_count");
	for(int type=k_Fish_Type_Red;type<k_Fish_Type_Count;type++){
		CCArray* spriteFrames=CCArray::createWithCapacity(frameCount);
		for(int i=0;i<frameCount;i++){
			CCString* fileName=CCString::createWithFormat(staticData->stringFromKey("fish_frame_name_format"),type,i);
			CCSpriteFrame* spriteFrame=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(fileName->getCString());
			spriteFrames->addObject(spriteFrame);
		}
		CCAnimation* fishAnimation=CCAnimation::createWithSpriteFrames(spriteFrames);
		fishAnimation->setDelayPerUnit(staticData->floatFromKey("fish_frame_delay"));
		CCString* animationName=CCString::createWithFormat(staticData->stringFromKey("fish_animation"),type);
		CCAnimationCache::sharedAnimationCache()->addAnimation(fishAnimation,animationName->getCString());
	}
}

void GameScene::onEnterTransitionDidFinish()
{
	CCScene::onEnterTransitionDidFinish();
	PersonalAudioEngine::getInstance().playBackgroundMusic(StaticData::getInstance()->stringFromKey("bg_music"),true);
}

bool GameScene::init()
{
	preloadResources();
	if(CCScene::init()){
		_backgroundLayer=BackgroundLayer::create();
		addChild(_backgroundLayer);
		_fishLayer=FishLayer::create();
		addChild(_fishLayer);
		_cannonLayer=CannonLayer::create();
		addChild(_cannonLayer);
		_panelLayer=PanelLayer::create();
		addChild(_panelLayer);
		_menuLayer=MenuLayer::create();
		CC_SAFE_RETAIN(_menuLayer);
		_isPaused=false;
		_touchLayer=TouchLayer::create();
		addChild(_touchLayer);
		scheduleUpdate();
		return true;
	}
	return false;
}

void GameScene::pause()
{
	if(!_isPaused){
		operateAllSchedulerAndActions(this,k_Operate_Pause);
		addChild(_menuLayer);
		PersonalAudioEngine::getInstance().pauseBackgroundMusic();
		PersonalAudioEngine::getInstance().playEffect(StaticData::getInstance()->stringFromKey("sound_button"));
		_isPaused=true;
	}
}

void GameScene::resume()
{
	operateAllSchedulerAndActions(this,k_Operate_Resume);
	removeChild(_menuLayer,false);
	PersonalAudioEngine::getInstance().resumeBackgroundMusic();
	_isPaused=false;
}

void GameScene::operateAllSchedulerAndActions(CCNode* node,OperateFlag flag)
{
	if(node->isRunning()){
		switch(flag){
		case k_Operate_Pause:
			node->pauseSchedulerAndActions();
			break;
		case k_Operate_Resume:
			node->resumeSchedulerAndActions();
			break;
		default:
			break;
		}
		CCArray* array=node->getChildren();
		if(array!=0 && array->count()>0){
			CCObject* iter;
			CCARRAY_FOREACH(array,iter){
				operateAllSchedulerAndActions(static_cast<CCNode*>(iter),flag);
			}
		}
	}
}

void GameScene::sound()
{
	float volume=FishingJoyData::getInstance()->getSoundVolume();
	PersonalAudioEngine::getInstance().setEffectsVolume(volume);
}

void GameScene::music()
{
	float volume=FishingJoyData::getInstance()->getMusicVolume();
	PersonalAudioEngine::getInstance().setBackgroundMusicVolume(volume);
}

void GameScene::cannonAimAt(CCPoint target)
{
	_cannonLayer->aimAt(target);
}

void GameScene::cannonShootTo(CCPoint target)
{
	int cannonType=_cannonLayer->getWeapon()->getCannon()->getType();
	int cost=cannonType+1;
	int curGold=FishingJoyData::getInstance()->getGold();
	if(curGold>=cost && _cannonLayer->shootTo(target)){
		alterGold(-cost);
		PersonalAudioEngine::getInstance().playEffect(StaticData::getInstance()->stringFromKey("sound_shot"));
	}
}

void GameScene::checkOutCollision()
{
	Weapon* weapon=_cannonLayer->getWeapon();
	if(weapon->getStatus()==k_Weapon_Status_Bullet){
		if(checkOutCollisionBetweenFishesAndBullet()){
			checkOutCollisionBetweenFishesAndFishingNet();
		}
	}
}

bool GameScene::checkOutCollisionBetweenFishesAndBullet()
{
	Weapon* weapon=_cannonLayer->getWeapon();
	CCPoint bulletCollision=weapon->getCollisionPoint();
	CCArray* fishes=_fishLayer->getFishes();
	CCObject* iter;
	CCARRAY_FOREACH(fishes,iter){
		Fish* fish=static_cast<Fish*>(iter);
		if(fish->isRunning()){
			CCRect fishCollisionArea=fish->getCollisionArea();
			bool isCollision=fishCollisionArea.containsPoint(bulletCollision);
			if(isCollision){
				weapon->end();
				return true;
			}
		}
	}
	return false;
}

void GameScene::checkOutCollisionBetweenFishesAndFishingNet()
{
	Weapon* weapon=_cannonLayer->getWeapon();
	CCRect netCollision=weapon->getCollisionArea();
	CCArray* fishes=_fishLayer->getFishes();
	CCObject* iter;
	CCARRAY_FOREACH(fishes,iter){
		Fish* fish=static_cast<Fish*>(iter);
		if(fish->isRunning()){
			CCRect fishCollisionArea=fish->getCollisionArea();
			bool isCollision=fishCollisionArea.intersectsRect(netCollision);
			if(isCollision){
				fishWillBeCaught(fish);
			}
		}
	}
}

void GameScene::fishWillBeCaught(Fish* fish)
{
	CannonType weaponType=_cannonLayer->getWeapon()->getCannonType();
	FishType fishType=fish->getType();
	CCString* fishPercentage=CCString::createWithFormat(StaticData::getInstance()->stringFromKey("fish_percentage_format"),fishType);
	CCString* weaponPercentage=CCString::createWithFormat(StaticData::getInstance()->stringFromKey("weapon_percentage_format"),weaponType);
	float fish_percentage=StaticData::getInstance()->floatFromKey(fishPercentage->getCString());
	float weapon_percentage=StaticData::getInstance()->floatFromKey(weaponPercentage->getCString());
	float percentage=weapon_percentage*fish_percentage;
	if(CCRANDOM_0_1()<percentage){
		fish->beCaught();
		CCString* rewardKey=CCString::createWithFormat(StaticData::getInstance()->stringFromKey("reward_format"),fishType);
		int reward=StaticData::getInstance()->intFromKey(rewardKey->getCString());
		alterGold(reward);
	}
}

void GameScene::update(float dt)
{
	checkOutCollision();
}

void GameScene::alterGold(int gValue)
{
	FishingJoyData* gameData=FishingJoyData::getInstance();
	gameData->alterGold(gValue);
	_panelLayer->getGoldCounterLayer()->setNumber(gameData->getGold());
}

void GameScene::scheduleTimeUp()
{
	alterGold(StaticData::getInstance()->intFromKey("recovery_gold"));
}
